/***************************************************************************
 *  Filename: messageparser.h
 *  Class: MessageParser
 *
 *  Copyright 2012  Xander van Kooten
 *  <xandervk@gmail.com>
 *
 *  Copyright 2012  Mario Henrique Voorsluys
 *  <forcaeluz@gmail.com>
 *
 ****************************************************************************/

/*
 *
 * This file is part of Parsax-Remote-Controller.
 *
 *    Parsax-Remote-Controller is free software: you can redistribute it
 *    and/or modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    Parsax-Remote-Controller is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Parsax-Remote-Controller.
 *    If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MESSAGEPARSER_H
#define MESSAGEPARSER_H

#include "CCC-Communication_global.h"
#include <QByteArray>
#include <QtCore>
#include <QString>


/*!
 \brief Handles packing and unpacking messages.

*/
class CCCCOMMUNICATIONSHARED_EXPORT MessageParser: public QObject
{
    Q_OBJECT
public:
    /*!
     \brief Create a MessageParser object.

     \param parent

     The MessageParser class has no properties, only functions. It's used to generate strings
     that are send between Controller and Slave. So no initialization is needed in the constructor.
    */
    explicit MessageParser(QObject *parent = 0);

    /*!
     \brief Generates a configuration message.

     \param configuration A map structure containing keys and values.
     \return QByteArray The message that should be sent throught the network.

     The message should be like: \#cfg\#values\#key1:value1\#key2:value2\#...\#keyN:valueN\#\#.
    */
    QByteArray configurationMessage(QMap<QString, QVariant> configuration);

    /*!
     \brief Generates a status message.

     \param id ID given to the program
     \param status Status of that program (starting/running/notrunning)
     \return QByteArray The message that should be sent throught the network.

     The message should be like: \#sta\#id\#status\#\#.
    */
    QByteArray statusMessage(QString id, QString status);

    /*!
     \brief Generates a CLO (Command Line Output) message.

     \param id The id of the program
     \param type Type of message (Normal=0 or Error=1)
     \param msg The message itself.
     \return QByteArray The message that should be sent throught the network.

     The message should be like: \#clo\#type\#messageline1\#messageline2\#...\#messagelineN\#\#.
    */
    QByteArray cloMessage(QString id, int type, QString msg);

    /*!
     \brief Generates a Program Message.

     \param id The id of the program.
     \param action Action that should be taken (Start/stop/restart).
     \return QByteArray The message that should be sent throught the network.

     The message should be like: \#prg\#id\#action\#\#.
    */
    QByteArray prgMessage(QString id, QString action);

    /*!
     \brief Generates a New Program Message.

     \param id The id that should be given to the new program
     \param program Program that should be started.
     \param params Parameters given to the program at start-up.
     \return QByteArray The message that should be sent throught the network.

     The message should be like: \#npr\#id\#progran\#param1\#param2\#...\#paramN\#\#.
    */
    QByteArray nprMessage(QString id, QString program, QStringList params);

public slots:

    /*!
     \brief Handles an incoming message.

     \param data The incoming message.

     Despite the fact that the messages are already checked by the previous level
     (MasterCommunicator and SlaveCommunicator), a validity check is performed here also.
     After this check the message is parsed, and an corresponding signal is emitted.
     \see cloReceived() statusReceived() configurationReceived() startProgramReceived()
     stopProgramReceived() setConfigurationReceived() getConfigurationReceived()
    */
    void handleMessage(QString data);

signals:

    /*!
     \brief Emmited when a CLO (Command Line Output) Message is received.

     \param id ID of the program.
     \param type Type of output (normal or error).
     \param msg The message itself.

     \see cloMessage()
    */
    void cloReceived(QString id, int type, QString msg);

    /*!
     \brief Emmited when a Status Message is received.

     \param id ID of the program.
     \param status The status of the program.

     \see statusMessage()
    */
    void statusReceived(QString id, QString status);

    /*!
     \brief Emmited when a Configuration Message is received.
        \todo To be implemented in the future.
     \param configuration The configuration map (Keys and values).
     \see configurationMessage()
    */
    void configurationReceived(QMap<QString, QVariant> configuration);

    /*!
     \brief Emmited when a Start Program Message is received.

     \param id ID of the program that should be started.
     \see prgMessage()
    */
    void startProgramReceived(QString id);

    /*!
     \brief Emmited when a Start New Program Message is received.

     \param id ID that this new program should have.
     \param program Program that should be started.
     \param parameters Parameters given to the program at start-up.
     \see nprMessage()
    */
    void startProgramReceived(QString id, QString program, QStringList parameters);

    /*!
     \brief Emmited when a Stop Program Message is received.

     \param id ID of the program that should be stopped.
     \see prgMessage()
    */
    void stopProgramReceived(QString id);

    /*!
     \brief Emmited when a Set Configuration Message is received.
        \todo To be implemented in the future.
     \param key
     \param value
    */
    void setConfigurationReceived(QString key, QVariant value);

    /*!
     \brief Emmited when a Get Configuration Message is received.
        \todo To be implemented in the future.
     \param keys
    */
    void getConfigurationReceived(QStringList keys);


    /*!
     \brief

     \param id
     \param input
    */
    void cmdReceived(QString id, QString input);
};

#endif // MESSAGEPARSER_H
